package blue.web.dao.service;

import blue.commons.enums.RuleTypeEnum;
import blue.commons.enums.StatusEnum;
import blue.commons.enums.TaskTypeEnum;
import blue.dao.base.BaseMapper;
import blue.splitclass.dao.ElectivePublishCourseMapper;
import blue.splitclass.model.*;
import blue.tools.commons.BlueStringUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.raistlic.common.permutation.Combination;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ElectivePublishCourseService extends BaseService {

    @Autowired
    private ElectivePublishCourseMapper electivePublishCourseMapper;

    @Autowired
    private BlueCourseService blueCourseService;

    @Autowired
    private ElectiveRuleService electiveRuleService;

    @Autowired
    private ElectiveTaskService electiveTaskService;


    public int deleteBatch(String ids) {

        List idList= BlueStringUtils.convertString2Num(ids,",");
        ElectivePublishCourseExample example=new ElectivePublishCourseExample();
        example.createCriteria().andIdIn(idList);

        return this.getBaseMapper().deleteByExample(example);
    }

    public int deleteByTaskId(Long taskId, Long schoolId) {

        if(taskId==null || schoolId==null){
            return 0;
        }

        ElectivePublishCourseExample example=new ElectivePublishCourseExample();
        ElectivePublishCourseExample.Criteria criteria=example.createCriteria().andSchoolidEqualTo(schoolId).andTaskIdEqualTo(taskId);


        return this.getBaseMapper().deleteByExample(example);
    }


    public int save(ElectivePublishCourse record) {

        if(record==null || (record.getTaskId()==null && record.getId()==null)){
            return 0;
        }

        ElectivePublishCourseExample example=new ElectivePublishCourseExample();
        ElectivePublishCourseExample.Criteria criteria=example.createCriteria().andSchoolidEqualTo(record.getSchoolid());

        if(record.getId()!=null){
            criteria.andIdEqualTo(record.getId());
        }else {
            if(record.getTaskId()!=null){
                criteria.andTaskIdEqualTo(record.getTaskId());
            }

            if(StringUtils.isNotBlank(record.getCourseIds())){
                criteria.andCourseIdsEqualTo(record.getCourseIds());
            }
        }


        return this.baseSave(record,example);

    }

    public List<ElectivePublishCourse> selectByTaskId(Long taskId,Short type, Long schoolId){

        if(taskId==null || schoolId==null){
            return null;
        }
        List<ElectivePublishCourse> list=new LinkedList<>();
        ElectiveTask electiveTask=electiveTaskService.selectById(taskId,schoolId);
        if(type==null){
            type=electiveTask.getType();
        }

        if(TaskTypeEnum.Course.getKey()==type){

            List<Long> courseList=BlueStringUtils.convertString2Num(electiveTask.getCourseIds(),",");
            for(Long courseId:courseList){
                ElectivePublishCourse electivePublishCourse=new ElectivePublishCourse();
                electivePublishCourse.setSelectedCount(0);
                electivePublishCourse.setName(String.format("单科程"));
                electivePublishCourse.setSchoolid(schoolId);
                electivePublishCourse.setTaskId(taskId);
                electivePublishCourse.setCourseIds(courseId.toString());
                list.add(electivePublishCourse);
            }
        }else {
            ElectivePublishCourseExample example=new ElectivePublishCourseExample();
            example.setOrderByClause("id asc");
            ElectivePublishCourseExample.Criteria criteria=example.createCriteria().andSchoolidEqualTo(schoolId).andTaskIdEqualTo(taskId).andTypeEqualTo(type);

            list=this.select(example);
        }

        if(CollectionUtils.isNotEmpty(list)){

            for(ElectivePublishCourse publishCourse:list){
                if(StringUtils.isNotBlank(publishCourse.getCourseIds())){
                    publishCourse.setCourseNameList(blueCourseService.selectByIds(publishCourse.getCourseIds(),schoolId));
                }
            }

        }
        return list;
    }


    public void createByRule(Long taskId,Long schoolId,int type){
        if(taskId==null || schoolId==null){
            return ;
        }

        ElectiveTask electiveTaskExtend=electiveTaskService.selectById(taskId,schoolId);
        if(electiveTaskExtend==null || electiveTaskExtend.getStatus().longValue()!=StatusEnum.RuleAlter.getValue()){
            return;
        }

        deleteByTaskId(taskId,schoolId);

        List<ElectivePublishCourse> electivePublishCourseList=getCombination(null,taskId,schoolId,true);
        if(CollectionUtils.isNotEmpty(electivePublishCourseList)){
            for(ElectivePublishCourse electivePublishCourse:electivePublishCourseList){
                electivePublishCourse.setType((short) type);
                this.save(electivePublishCourse);
            }
        }
        electiveTaskExtend.setStatus((byte) StatusEnum.Normal.getValue());
        electiveTaskService.save(electiveTaskExtend);
    }


    private void createCombination(ElectiveRule electiveRule,List requiredCourses){
        String courseIds=electiveRule.getCourseIds();
        if(StringUtils.isBlank(courseIds)){
            return;
        }

        List courseIdList=BlueStringUtils.convertString2Num(courseIds,",");
        int count=1;
        for(int i=electiveRule.getMinCount();i<=electiveRule.getMaxCount();i++){
            Combination<Long> combination = Combination.of(courseIdList, i);
            for (List<Long> list : combination) {
                if(!list.containsAll(requiredCourses)){
                    continue;
                }
                ElectivePublishCourse electivePublishCourse=new ElectivePublishCourse();
                electivePublishCourse.setCourseIds(StringUtils.join(list,","));
                electivePublishCourse.setTaskId(electiveRule.getTaskId());
                electivePublishCourse.setSchoolid(electiveRule.getSchoolid());
                electivePublishCourse.setName(String.format("组合%s",count++));
                electivePublishCourse.setSelectedCount(0);
                electivePublishCourse.setType(electiveRule.getType());
                this.save(electivePublishCourse);
            }
        }
    }


    public List<ElectivePublishCourse> getCombination(List courseList,Long taskId,Long schoolId,boolean checkRequired){

        int count=1;
        List result=new LinkedList();

        ElectiveRuleObject electiveRuleObject=getRequiredCourse(taskId,schoolId);
        ElectiveRule mainElectiveRule=electiveRuleObject.getMainRule();
        List requiredCourses=electiveRuleObject.getRequiredCourse();

        if(mainElectiveRule==null){
            return null;
        }

        if(CollectionUtils.isEmpty(courseList) && StringUtils.isNotBlank(mainElectiveRule.getCourseIds())){
            courseList=BlueStringUtils.convertString2Num(mainElectiveRule.getCourseIds(),",");
        }

        for(int i=mainElectiveRule.getMinCount();i<=mainElectiveRule.getMaxCount();i++){
            Combination<Long> combination = Combination.of(courseList, i);
            for (List<Long> list : combination) {
                if(checkRequired){
                    if(!list.containsAll(requiredCourses)){
                        continue;
                    }
                }
                ElectivePublishCourse electivePublishCourse=new ElectivePublishCourse();
                electivePublishCourse.setCourseIds(StringUtils.join(list,","));
                electivePublishCourse.setTaskId(mainElectiveRule.getTaskId());
                electivePublishCourse.setSchoolid(mainElectiveRule.getSchoolid());
                electivePublishCourse.setName(String.format("组合%s",count++));
                electivePublishCourse.setSelectedCount(0);
                electivePublishCourse.setType(mainElectiveRule.getType());
                result.add(electivePublishCourse);
            }
        }

        return result;
    }

    public ElectiveRuleObject getRequiredCourse(Long taskId, Long schoolId){
        if(taskId==null || schoolId==null){
            return null;
        }

        ElectiveRule rule=new ElectiveRule();
        rule.setTaskId(taskId);
        rule.setSchoolid(schoolId);
        List<ElectiveRule> electiveRuleList=electiveRuleService.selectByObject(rule,true);

        if(CollectionUtils.isEmpty(electiveRuleList)){
            return null;
        }
        ElectiveRule mainElectiveRule=null;
        List requiredCourses=new LinkedList();
        for(ElectiveRule electiveRule:electiveRuleList){
            if(electiveRule.getType()==RuleTypeEnum.Main.getKey()){
                mainElectiveRule=electiveRule;
            }else if(electiveRule.getType()==RuleTypeEnum.Required.getKey()){
                String courseIds=electiveRule.getCourseIds();
                if(StringUtils.isBlank(courseIds)){
                    continue;
                }

                requiredCourses.addAll(BlueStringUtils.convertString2Num(courseIds,","));
            }
        }

        ElectiveRuleObject electiveRuleObject=new ElectiveRuleObject();
        electiveRuleObject.setMainRule(mainElectiveRule);
        electiveRuleObject.setRequiredCourse(requiredCourses);
        return electiveRuleObject;
    }



    private List<ElectivePublishCourse> sort(List<ElectivePublishCourse> list){

        if(CollectionUtils.isEmpty(list)){
            return list;
        }

        Collections.sort(list,new Comparator<ElectivePublishCourse>(){

            @Override
            public int compare(ElectivePublishCourse o1, ElectivePublishCourse o2) {
                return o1.getName().compareToIgnoreCase(o2.getName());
            }
        });

        return list;
    }


    @Override
    public BaseMapper getBaseMapper() {
        return this.electivePublishCourseMapper;
    }

    @Override
    public void clearCache(Long schoolId,Object... extend) {

    }
}
